﻿#pragma once
#include <chrono>
#include "yzrutil.h"
#include "array/Array.hpp"
#include "util/Util.h"
#include "io/PrintStream.h"
#include "io/FilterInputStream.h"

namespace yzrilyzr_lang{
	EBCLASS(System){
	private:
	static yzrilyzr_io::OutputStream & createOutStream();
	static yzrilyzr_io::InputStream & createInputStream();
	public:
	static inline yzrilyzr_io::PrintStream out{createOutStream(), true};
	static inline yzrilyzr_io::FilterInputStream in{createInputStream()};
	static u_time_stamp nanoTime(){
		auto now=std::chrono::high_resolution_clock::now();
		auto duration=now.time_since_epoch();
		auto nanos=std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
		u_time_stamp ns=static_cast<u_time_stamp>(nanos);
		return ns;
	}
	static u_time_stamp currentTimeMillis(){
		auto now=std::chrono::high_resolution_clock::now();
		auto duration=now.time_since_epoch();
		auto millis=std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
		u_time_stamp ms=static_cast<u_time_stamp>(millis);
		return ms;
	}
	template<typename T>
	static void arraycopy(const yzrilyzr_array::Array<T> &src, u_index srcOffset, yzrilyzr_array::Array<T>&dst, u_index dstOffset, u_index length){
		yzrilyzr_util::Util::checkRange(src.length, srcOffset, srcOffset + length);
		yzrilyzr_util::Util::checkRange(dst.length, dstOffset, dstOffset + length);
		if(std::is_trivially_copyable<T>::value){
			if(&src == &dst && srcOffset < dstOffset){
				// 向后拷贝，使用memmove
				memmove(dst._array + dstOffset, src._array + srcOffset, length * sizeof(T));
			} else{
				memcpy(dst._array + dstOffset, src._array + srcOffset, length * sizeof(T));
			}
		} else{
			// 对于非平凡类型，使用赋值操作
			if(&src == &dst){
			// 同一数组内的拷贝
				if(srcOffset < dstOffset){
					// 向后拷贝，需要从后往前避免覆盖
					for(u_index i=length; i > 0; --i){
						dst._array[dstOffset + i - 1]=std::move(src._array[srcOffset + i - 1]);
					}
				} else{
					// 向前拷贝，正常顺序
					for(u_index i=0; i < length; ++i){
						dst._array[dstOffset + i]=std::move(src._array[srcOffset + i]);
					}
				}
			} else{
				// 不同数组间的拷贝
				for(u_index i=0; i < length; ++i){
					dst._array[dstOffset + i]=src._array[srcOffset + i];
				}
			}
		}
	}
	};
}